

#include <ctime>
#include "Socket.hpp"
#include "Protocol.hpp"

using namespace socket_ns;
using namespace log_ns;

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        std::cerr << "Usage: " << argv[0] << " Server-IP Server-Port" << std::endl;
        exit(0);
    }
    std::string serverIP = argv[1];
    in_port_t serverPort = std::stoi(argv[2]);

    SockSPtr socket = std::make_shared<TcpSocket>();
    if (!socket->BuildClientSocket(serverIP, serverPort))
    {
        std::cerr << "Connect Error" << std::endl;
        exit(1);
    }

    srand(time(nullptr) ^ getgid());
    const std::string opers = "+-*/%&|!^";

    std::string packagestreamqueue;

    while (true)
    {
        // 构建数据
        int x = rand() % 10;
        usleep(x * 1000);
        int y = rand() % 10;
        usleep(x * y * 1000);
        char oper = opers[y % opers.size()];

        // 构建请求
        auto req = Factory::BuildRequestDefault();
        req->SetValue(x, y, oper);

        // 序列化
        std::string reqstr;
        req->Serialize(&reqstr);

        // 添加报文长度
        reqstr = Encode(reqstr);
        LOG(INFO, "Request String:\n%s", reqstr.c_str());
        // std::cout << "Request String: " << reqstr << std::endl;

        // 发送数据
        int n = socket->Send(reqstr);
        if (n == 0)
        {
            LOG(WARNING, "Send Nothing?\n");
            break;
        }
        else if (n < 0)
        {
            LOG(ERROR, "Send() -> Error, errno: %d -> %s\n", errno, strerror(errno));
            break;
        }

        // 读取应答
        while (true)
        {
            // 接收报文字节流
            ssize_t n = socket->Recv(&packagestreamqueue);
            if (n == 0)
            {
                LOG(WARNING, "Send Nothing?\n");
                break;
            }
            else if (n < 0)
            {
                LOG(ERROR, "recv() -> Error, errno: %d -> %s\n", errno, strerror(errno));
                break;
            }
            // 提取完整报文
            std::string package = Decode(packagestreamqueue);
            if (package.empty())
                continue;

            // 反序列化
            auto resp = Factory::BuildResponseDefault();
            resp->Deserialize(package);

            // 打印结果
            resp->Print();
            break;
        }
        sleep(1);
    }

    socket->CloseSockfd();

    return 0;
}
